package cn.iocoder.yudao.module.reading.service.community;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.module.reading.controller.app.community.vo.draft.DraftCreateReqVO;
import cn.iocoder.yudao.module.reading.controller.app.community.vo.draft.DraftRespVO;
import cn.iocoder.yudao.module.reading.convert.community.CommunityDraftConvert;
import cn.iocoder.yudao.module.reading.dal.dataobject.community.CommunityDraftDO;
import cn.iocoder.yudao.module.reading.dal.mysql.community.CommunityDraftMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;

import jakarta.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 社区草稿服务实现类
 *
 * @author 芋道源码
 */
@Service
@Slf4j
public class CommunityDraftServiceImpl implements CommunityDraftService {

    @Resource
    private CommunityDraftMapper draftMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long saveDraft(DraftCreateReqVO createReqVO, Long userId) {
        // 1. 业务验证：草稿至少要有内容或图片之一
        String content = createReqVO.getContent();
        List<String> images = createReqVO.getImages();

        boolean hasContent = content != null && !content.trim().isEmpty();
        boolean hasImages = CollUtil.isNotEmpty(images);

        if (!hasContent && !hasImages) {
            throw new ServiceException(BAD_REQUEST.getCode(), "草稿内容和图片不能同时为空");
        }

        // 2. 删除用户之前的草稿（每个用户每种类型只保留一个草稿）
        draftMapper.deleteByUserIdAndType(userId, createReqVO.getType());

        // 3. 转换并保存新草稿
        CommunityDraftDO draft = CommunityDraftConvert.INSTANCE.convert(createReqVO);
        draft.setUserId(userId);
        draft.setExpireTime(CommunityDraftConvert.INSTANCE.calculateExpireTime());

        // 处理内容：如果为空字符串，设置为空格以避免数据库约束问题
        if (content == null || content.trim().isEmpty()) {
            draft.setContent(" ");
        } else {
            draft.setContent(content.trim());
        }

        // 处理图片JSON
        if (CollUtil.isNotEmpty(createReqVO.getImages())) {
            draft.setImages(CommunityDraftConvert.INSTANCE.convertImagesToJson(createReqVO.getImages()));
        }
        
        draftMapper.insert(draft);
        
        log.info("[saveDraft][草稿保存成功] draftId: {}, userId: {}, type: {}", 
                draft.getId(), userId, createReqVO.getType());
        
        return draft.getId();
    }

    @Override
    public DraftRespVO getLatestDraft(Long userId, String type) {
        CommunityDraftDO draft = draftMapper.selectLatestByUserIdAndType(userId, type);
        return CommunityDraftConvert.INSTANCE.convert(draft);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteDraft(Long userId, String type) {
        draftMapper.deleteByUserIdAndType(userId, type);
        log.info("[deleteDraft][草稿逻辑删除成功] userId: {}, type: {}", userId, type);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void physicalDeleteDraft(Long userId, String type) {
        draftMapper.physicalDeleteByUserIdAndType(userId, type);
        log.info("[physicalDeleteDraft][草稿物理删除成功] userId: {}, type: {}", userId, type);
    }

    @Override
    @Scheduled(cron = "0 0 2 * * ?") // 每天凌晨2点执行
    @Transactional(rollbackFor = Exception.class)
    public void cleanExpiredDrafts() {
        // 使用物理删除清理过期草稿
        draftMapper.physicalDeleteExpiredDrafts(LocalDateTime.now());

        log.info("[cleanExpiredDrafts][清理过期草稿完成] expireTime: {}", LocalDateTime.now());
    }

}
